/*
 * Copyright © 2017 eqxiu.com 北京中网易企秀科技有限公司  All rights reserved.
 */

package cn.hermit.nio.server;

import cn.hermit.core.Disposable;

import java.io.IOException;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author JackGao 高建国
 * @description //TODO 设计说明
 * @date 17/5/2017
 */
public class NioWorker implements Runnable, Disposable {

    private static final Logger logger = Logger.getLogger(NioServer.class.getName());

    private volatile boolean closed;

    private List<ServerDataEvent> queue = new LinkedList();

    public void processData(NioServer server, SocketChannel socket, byte[] data, int count) {
        byte[] dataCopy = new byte[count];
        System.arraycopy(data, 0, dataCopy, 0, count);
        synchronized (queue) {
            queue.add(new ServerDataEvent(server, socket, dataCopy));
            queue.notify();
        }
    }

    public void run() {
        ServerDataEvent dataEvent;

        while (!closed) {
            // Wait for data to become available
            synchronized (queue) {
                while (queue.isEmpty()) {
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                    }
                }
                dataEvent = queue.remove(0);
            }

            logger.log(Level.FINE, "Nio Worker in Thread[{0}] is processing data.", String.valueOf(Thread.currentThread().getId()));

            dataEvent.server.getRequestHandler().handle(dataEvent);
        }
    }

    @Override
    public void destroy() {
        try {
            closed = true;
            for (ServerDataEvent event : this.queue) {
                event.socket.close();
            }
            this.queue.clear();
        } catch (IOException e) {
            //ignored
        }
    }
}